import sys
import ConfigParser

class CommParser(ConfigParser.ConfigParser):

    def as_dict(self):
        d = dict(self._sections)
        for key in d:
            d[key] = dict(self._defaults, **d[key])
            d[key].pop('__name__', None)
        for key in d["COMMANDS"]:
            val_list = d["COMMANDS"][key].split()
            if(len(val_list) > 1):
                d["COMMANDS"][key] = (val_list[0], val_list[1:])
            else:
                d["COMMANDS"][key] = (val_list[0], [])
        return d["COMMANDS"]


class CommandParser():
   
    def __init__(self, confidenceThreshold=10):
        self.confidenceThreshold = confidenceThreshold
        self.commands = {}
        
    def readCommandConfig(self, fileName):
        #print("filename" + fileName)
        
        '''
        Reads command configuration from ini file.
        Stores the information to a dictionary.
        Returns the dictionary and also stores it as a class attribute,
        in error situation returns False
        '''

        # Configuration will be read into a dictionary:
        # KEY is the finnish command
        # VALUE is a pair containing corresponding function name in controlNao.py and its parameters
        configuration = {}
        
        
        try:
            comm_parser = CommParser()
            comm_parser.read(fileName)
            configuration = comm_parser.as_dict()
            self.commands= configuration
            return True
            
            
        except IOError:
            print ("Error with config file " + fileName)
            return False
        
        
    def parseStringFromAaltoASR(self, stringFromAaltoASR):
        '''
        Parses the AaltoASR recognition result.
        Returns a pair which contains <function_name> and 
        <list_of_function_params> 
        See controlNao.py for available functions
        
        If the command is not found, the function will return False
        
        stringFromAaltoASR looks something like this:
        RESULT: <s> istu </s>
        CONFIDENCE: 772.157
        
        '''
        
        stringParts = stringFromAaltoASR.split(':')
        
        #Error handling
        if(len(stringParts) < 2):
            return False
         
        commandIdx = 0
        for idx in range(len(stringParts)):
            if  "RESULT" in stringParts[idx]:
                commandIdx = idx + 1
                
        if commandIdx == 0: 
            return False #Some error in stringFromAaltoASR because "RESULT" not found
        
        confidence = float(stringParts[commandIdx +1].strip())
        if confidence > self.confidenceThreshold:
            return False
        
        #remove unwanted part
        commandToParse = stringParts[commandIdx].replace('CONFIDENCE', '')
        #parse actual command
        finnishCommand = self.parseFinnishCommand(commandToParse)
        if finnishCommand:
            return self.commands[finnishCommand]
        else:
            return False
                    
    def parseFinnishCommand(self, commandToParse):    
        #remove <s> and </s> tags 
        commandToParse = commandToParse.replace('<s>', '')
        commandToParse = commandToParse.replace('</s>','')
        
        commandParts = commandToParse.split()
        
        for command in commandParts:
            if command in self.commands:
                return command
        
        return "" #NOT FOUND
    
             
if __name__ == '__main__':
    # Main for unit testing
    
    parser = CommandParser()
  
    if(len(sys.argv) < 2):
        print ("Usage: <path to config file>")
    else:
        fileName = sys.argv[1]
    
        parser = CommandParser()
        
        returnValue = parser.readCommandConfig(fileName)
        print("PARSER COMMANDS: ")
        print(parser.commands)
        
        print ("Parser returned after reading " + fileName +":\n" + str(returnValue))
        print("---------\nTest command parsing")
        
        stringFromAaltoASR = "RESULT:  <s> istu </s> <s> seiso </s>\nCONFIDENCE: 879.144043\n"
        print("AaltoASR string to parse: " + stringFromAaltoASR)
        
        parsed = parser.parseStringFromAaltoASR(stringFromAaltoASR)
        print("command to send to Nao: " + str(parsed))
        
        print("len of command params: " + str(len(parsed[1])))
        print ("first command param: " + parsed[1][0])
        
        
    
